/*java jdk 1.7+
# -*- coding: utf-8 -
'''
Created on 2020年05月10日
@author: zxyong 13738196011
'''*/

package com.zxy.common;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlExpression;
import org.apache.commons.jexl3.MapContext;

import com.zxy.business.Ope_DB_Cent;
import com.zxy.model.cal_fun;
import com.zxy.model.cal_run;
import com.zxy.model.cal_run_param;
import com.zxy.model.cal_run_step;
import com.zxy.model.cal_variables;

public class Cal_Auto_Run
{
	public static long								Real_date			= 0;
	public static Hashtable<String, String[]>		ht_cond__real_value	= null;
	public static Hashtable<Integer, cal_variables>	ht_cal_variables	= null;
	public static Hashtable<Integer, cal_fun>		ht_cal_fun			= null;
	public static Hashtable<String, cal_run>		ht_cal_run			= null;
	public static List<cal_run_param>				list_cal_run_param	= null;
	public static List<cal_run_step>				list_cal_run_step	= null;
	private static final JexlEngine					JEXL				= new JexlBuilder().create();
	public static String							Cal_Desc			= "";
	public static String							input_Data			= "";

	public static void init_data()
	{
		Ope_DB_Cent opd = new Ope_DB_Cent();
		// 变量
		Cal_Auto_Run.ht_cal_variables = opd.Get_cal_variables();
		// 函数
		Cal_Auto_Run.ht_cal_fun = opd.Get_cal_fun();
		// 执行
		Cal_Auto_Run.ht_cal_run = opd.Get_cal_run();
		// 参数
		Cal_Auto_Run.list_cal_run_param = opd.Get_cal_run_param();
		// 运行步骤
		Cal_Auto_Run.list_cal_run_step = opd.Get_cal_run_step();
		// 工况实时数据 key为code|station_type格式 value为datetime|double格式
		if(java.util.Objects.equals(Cal_Auto_Run.ht_cond__real_value,null))
			Cal_Auto_Run.ht_cond__real_value = new Hashtable<String, String[]>();
	}

	public static boolean RunCal(String strExp, Root_Cal rc)
	{
		Cal_Auto_Run.input_Data = "";
		boolean bResult = true;
		String[] RunCode = strExp.replace(" ","").replace("\\(","").replace("\\)","").replace("\\|","\\&").split("&&");
		Boolean[] RunValue = new Boolean[RunCode.length];
		int iIndex = 0;
		for(String strRunCode: RunCode)
		{
			cal_run temc = (cal_run) (Cal_Auto_Run.ht_cal_run.get(strRunCode));
			cal_fun temf = (cal_fun) (Cal_Auto_Run.ht_cal_fun.get(temc.FUN_ID));
			List<cal_variables> lst_var = new ArrayList<cal_variables>();
			for(cal_run_param crp: Cal_Auto_Run.list_cal_run_param)
			{
				if(crp.RUN_ID == temc.MAIN_ID)
				{
					cal_variables cva = Cal_Auto_Run.ht_cal_variables.get(crp.VARI_ID);
					lst_var.add(cva);
				}
			}
			Class[] claP = new Class[lst_var.size()];
			Object[] objV = new Object[lst_var.size()];
			try
			{
				int jIndex = 0;
				for(cal_variables crp: lst_var)
				{
					if(crp.VAR_TYPE.equals("INT"))
						claP[jIndex] = Integer.class;
					else if(crp.VAR_TYPE.equals("STRING"))
						claP[jIndex] = String.class;
					else if(crp.VAR_TYPE.equals("DOUBLE"))
						claP[jIndex] = Double.class;
					else if(crp.VAR_TYPE.equals("INT[]"))
						claP[jIndex] = Integer[].class;
					else if(crp.VAR_TYPE.equals("STRING[]"))
						claP[jIndex] = String[].class;
					else if(crp.VAR_TYPE.equals("DOUBLE[]"))
						claP[jIndex] = Double[].class;

					for(Field field: rc.getClass().getDeclaredFields())
					{
						if(field.getName().equals(crp.VAR_NAME))
						{
							objV[jIndex] = Com_Fun.getFieldValueByName(field.getName(),rc);
							Cal_Auto_Run.input_Data += String.valueOf(objV[jIndex])
									+ ",";
							break;
						}
					}
					jIndex++;
				}
				boolean bTemT = (Boolean) rc.getClass().getMethod(temf.FUN_NAME,claP).invoke(rc,objV);
				RunValue[iIndex] = bTemT;
			}
			catch(Exception e)
			{
				Com_Fun.debug_in(e,Cal_Auto_Run.class.toString(),"公式错误");
				for(Object oj: objV)
				{
					System.out.println("参数:" + oj);
				}
			}
			iIndex++;
		}
		bResult = Cal_Auto_Run.Cal_Exp(strExp,RunCode,RunValue);
		if(!bResult)
		{
			Cal_Auto_Run.Cal_Desc = strExp + "][";
			for(Boolean rv: RunValue)
				Cal_Auto_Run.Cal_Desc += String.valueOf(rv) + ",";
		}else
			Cal_Auto_Run.Cal_Desc = "";
		return bResult;
	}

	public static boolean Cal_Exp(String expression, String[] strText, Boolean[] bValue)
	{
		JexlContext jexlContext = new MapContext();
		int iIndex = 0;
		for(String strTem: strText)
		{
			jexlContext.set(strTem,bValue[iIndex]);
			iIndex++;
		}
		JexlExpression e = JEXL.createExpression(expression);
		Boolean num = (Boolean) e.evaluate(jexlContext);
		return num;
	}
}